package block

import (
	"github.com/boltdb/bolt"
	"log"
)

// ---------------迭代器------------

// 检查区块链
/*
(1)现在，产生的所有块都会被保存到一个数据库里面，所以我们可以重新打开一个链，然后向里面加入新块。
但是在实现这一点后，我们失去了之前一个非常好的特性：再也无法打印区块链的区块了，因为现在不是将区块存储在一个数组，而是放到了数据库里面。
让我们来解决这个问题！

(2)BoltDB 允许对一个 bucket 里面的所有 key 进行迭代，但是所有的 key 都以字节序进行存储，
而且我们想要以区块能够进入区块链中的顺序进行打印。
此外，因为我们不想将所有的块都加载到内存中（因为我们的区块链数据库可能很大！或者现在可以假装它可能很大），我们将会一个一个地读取它们。
故而，我们需要一个区块链迭代器（BlockchainIterator）：
*/
type BlockchainIterator struct {
	currentHash 	[]byte// 当前块hash
	db 				*bolt.DB// 数据库连接
}

// 查询块：迭代器中查找下一个块
func (bci *BlockchainIterator)Next() *Block {
	var block *Block

	// 从数据库里面进行只读操作查询数据
	err := bci.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(BlocksBucket))
		// 获取键值Bucket.Get()
		encodeBlock := b.Get(bci.currentHash)
		block = DeserializeBlock(encodeBlock)

		return  nil
	})

	if err != nil {
		log.Panic(err)
	}

	bci.currentHash = block.PreBlockHash

	return block
}